home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Grab Bag
/
Shareware Grab Bag.iso
/
007
/
exec1.arc
/
EXEC1.DSM
next >
Wrap
Text File
|
1985-08-30
|
20KB
|
403 lines
; Author: Jon Wesener
; Date: 3 / 25 / 85
; Purpose: This program listing is the EXEC function 4Bh
; supplied by IBM's Command Shell. It was taken out
; of memory on a 256k PC. This code is at the top
; of memory and is called by the resident portion
; of the Command Shell which passes the parameters in
; memory instead of the registers.
; Included are 3 undocumented findings. The first
; is the storage of the stack registers in the calling
; programs PSP. Secondly, function 51 of DOS's INT 21
; which sets up a PSP at the segment pointed to by DX.
; And last, that AL = 01 to the EXEC function will load
; a program and pass its stack and starting position
; back to the caller in an extended Parameter Block.
; DATA area begins at offset 54Eh
3FA7:054E 1C 0B ..
3FA7:0550 60 13 00 05 00 4B 15 00-00 00 01 3B 15 FE FF 3B `....K.....;.~.;
3FA7:0560 15 36 15 C5 2A 3B 15 00-B4 30 CD 21 86 E0 3D 00 .6.E*;..40M!.`=.
3FA7:0570 02 73 09 BA 77 2B B4 09-CD 21 CD 20 B4 51 CD 21 .s.:w+4.M!M 4QM!
3FA7:0580 89 1E 5D 2B 4B 15 00 B4-3F 3B 15 09 00 00 00 00 ..]+K..4?;......
OFFSET NAME PURPOSE
------ ---- -------
054E prm_off temporary offset hold
0550 prm_seg temporary segment hold
0552 exe_fnc bit 2 - load overlay
0553 channel dos program file handle
0555 relo_fctr offset where load module will be loaded
0557 ld_siz size of load module in paragraphs
0559 strt_off start offset for new process
055B strt_seg start segment of new process
055D nstk_sp stack offset for new process
055F new_Stk stack segment for new process
0561 new_env new copied environment
0563 new_siz size of new program segment
0565 psp_seg where program will be loaded
0567 hgh_low this is the high\low loader switch !
0568 pgm_hdr 1e bytes for EXE header and 7 relocation elements
056C pgm_siz size of file in pages
056E relo_itm # of relocation items in the header
0570 hdr_siz size of header in paragraphs
0572 min_par minimum paragraphs needed above file
0574 max_par maximum paragraphs above file needed
0576 stk_seg the stack seg passed in by the linker
0578 stk_sp the stack offs passed in by the linker
057C str_ip the start offset from the linker
0584 str_seg where load module will be loaded
0586 ctl_cflg control-c check before int called
0587 ovrwrt overwrite address for environment
0589 cll_psp calling programs PSP
058B cur_dsk current disk drive
; CODE begins at offset 0h
3FA7:0000 0E PUSH CS
3FA7:0001 1F POP DS ; pt to internal data
3FA7:0002 B80033 MOV AX,3300
3FA7:0005 CD21 INT 21 ; check CTRL - C status
3FA7:0007 88168605 MOV [Ctl_CFLG],DL ; save it
3FA7:000B 33D2 XOR DX,DX
3FA7:000D B80133 MOV AX,3301
3FA7:0010 CD21 INT 21 ; turn off CRTL-C check
3FA7:0012 B451 MOV AH,51
3FA7:0014 CD21 INT 21
3FA7:0016 891E8905 MOV [cll_psp],BX ; get calling procs PSP
3FA7:001A 1E PUSH DS ; later changed to new
3FA7:001B 8EDB MOV DS,BX ; procs PSP
3FA7:001D 36 SS:
3FA7:001E C41EB30B LES BX,[0BB3] ; save calling programs
3FA7:0022 8C063000 MOV [0030],ES ; stack inside his PSP at
3FA7:0026 891E2E00 MOV [002E],BX ; PSP + 30h & 2Eh
3FA7:002A 1F POP DS ; this is undocumented
3FA7:002B B419 MOV AH,19
3FA7:002D CD21 INT 21 ; get current disk
3FA7:002F 8AD0 MOV DL,AL
3FA7:0031 B40E MOV AH,0E
3FA7:0033 CD21 INT 21 ; reset current disk
3FA7:0035 A28B05 MOV [cur_dsk],AL ; save what it is
3FA7:0038 B104 MOV CL,04
3FA7:003A B8D200 MOV AX,00D2
3FA7:003D D3E8 SHR AX,CL
3FA7:003F 0E PUSH CS ; this mess pts to the code
3FA7:0040 5B POP BX ; further ahead to check if
3FA7:0041 03C3 ADD AX,BX ; the environment was copied
3FA7:0043 A38705 MOV [ovrwrt],AX ; on top of this code !
3FA7:0046 E8EF04 CALL 0538
3FA7:0049 8B04 MOV AX,[SI] ; restore exec function
3FA7:004B 8B5C02 MOV BX,[SI+02] ; restore parm block offs
3FA7:004E 8B5406 MOV DX,[SI+06] ; restore name offs
3FA7:0051 8E4410 MOV ES,[SI+10] ; restore parm seg
3FA7:0054 8E5C0E MOV DS,[SI+0E] ; restore name seg
3FA7:0057 3C03 CMP AL,03 ; load overlay or prog
3FA7:0059 7607 JBE 0062 ; yep
3FA7:005B B001 MOV AL,01 ; signal invalid function
3FA7:005D E9B804 JMP 0518 ; and report error <--+
3FA7:0060 EBFB JMP 005D ; pts to above -------+
3FA7:0062 3C02 CMP AL,02 ; test for invalid function
3FA7:0064 74F5 JZ 005B ; signal invalid function
3FA7:0066 2E CS:
3FA7:0067 891E4E05 MOV [prm_off],BX ; save parm block offs
3FA7:006B 2E CS:
3FA7:006C 8C065005 MOV [prm_seg],ES ; save parm block seg
3FA7:0070 2E CS:
3FA7:0071 A25205 MOV [exe_fnc],AL ; save the function
3FA7:0074 2E CS:
3FA7:0075 C606670500 MOV BYTE PTR [0567],00
3FA7:007A B8003D MOV AX,3D00
3FA7:007D CD21 INT 21 ; open the file
3FA7:007F 72DF JB 0060 ; error if not found
3FA7:0081 2E CS:
3FA7:0082 A35305 MOV [channel],AX ; save the file handle
3FA7:0085 8BD8 MOV BX,AX
3FA7:0087 B80044 MOV AX,4400
3FA7:008A CD21 INT 21 ; get device status
3FA7:008C F6C280 TEST DL,80 ; test for eof
3FA7:008F 7404 JZ 0095 ; load whatever
3FA7:0091 B002 MOV AL,02 ; signal file not found
3FA7:0093 EBCB JMP 0060
3FA7:0095 2E CS: ; zero new psp seg
3FA7:0096 C70665050000 MOV WORD PTR [psp_seg],0000
3FA7:009C 2E CS:
3FA7:009D F606520502 TEST BYTE PTR [exe_fnc],02
3FA7:00A2 7560 JNZ 0104 ; go load overlay
3FA7:00A4 2E CS:
3FA7:00A5 C5364E05 LDS SI,[prm_off]
3FA7:00A9 8B04 MOV AX,[SI] ; get environment seg
3FA7:00AB 0BC0 OR AX,AX ; from parm block
3FA7:00AD 7510 JNZ 00BF ; we have supplied environment
3FA7:00AF 2E CS:
3FA7:00B0 8E1E8905 MOV DS,[cll_psp] ; get Calling procs PSP
3FA7:00B4 A12C00 MOV AX,[002C] ; read it from its PSP
3FA7:00B7 2E CS:
3FA7:00B8 A36105 MOV [new_env],AX ; store ENV seg to be copied
3FA7:00BB 0BC0 OR AX,AX
3FA7:00BD 7445 JZ 0104 ; doesn't have an environment
3FA7:00BF FC CLD
3FA7:00C0 8EC0 MOV ES,AX
3FA7:00C2 33FF XOR DI,DI
3FA7:00C4 B9FF7F MOV CX,7FFF ; MAX SIZE of a valid env
3FA7:00C7 32C0 XOR AL,AL ; look for zeros
3FA7:00C9 F2 REPNZ
3FA7:00CA AE SCASB
3FA7:00CB 7405 JZ 00D2 ; found end of a string
3FA7:00CD B00A MOV AL,0A
3FA7:00CF E99E00 JMP 0170 ; signal invalid env
3FA7:00D2 AE SCASB ; check for double zero
3FA7:00D3 75F4 JNZ 00C9 ; not there yet
3FA7:00D5 57 PUSH DI ; save size of env
3FA7:00D6 8BDF MOV BX,DI
3FA7:00D8 83C30F ADD BX,+0F ; round up
3FA7:00DB B104 MOV CL,04
3FA7:00DD D3EB SHR BX,CL ; convert to segments
3FA7:00DF 06 PUSH ES
3FA7:00E0 B448 MOV AH,48
3FA7:00E2 CD21 INT 21 ; allocate mem for new env
3FA7:00E4 1F POP DS ; pt to old env
3FA7:00E5 59 POP CX ; get size
3FA7:00E6 7303 JNB 00EB ; no probs allocating mem
3FA7:00E8 E97F00 JMP 016A ; not enough mem err
3FA7:00EB 8EC0 MOV ES,AX ; pt to new env with es
3FA7:00ED 2E CS:
3FA7:00EE A36105 MOV [new_env],AX ; save ptr to new env
3FA7:00F1 51 PUSH CX ; save size of env
3FA7:00F2 8CC1 MOV CX,ES
3FA7:00F4 03CB ADD CX,BX ; see if we step on our tail
3FA7:00F6 2E CS:
3FA7:00F7 3B1E8705 CMP BX,[ovrwrt] ; will we write over ourself?
3FA7:00FB 59 POP CX ; get size back
3FA7:00FC 776C JA 016A
3FA7:00FE 33F6 XOR SI,SI
3FA7:0100 33FF XOR DI,DI
3FA7:0102 F3 REPZ
3FA7:0103 A4 MOVSB ; copy old env to new
3FA7:0104 0E PUSH CS
3FA7:0105 1F POP DS
3FA7:0106 B91E00 MOV CX,001E ; read first 1eh bytes
3FA7:0109 8B1E5305 MOV BX,[channel] ; of program into data area
3FA7:010D BA6805 MOV DX,pgm_hdr
3FA7:0110 06 PUSH ES
3FA7:0111 1E PUSH DS
3FA7:0112 E8CC03 CALL 04E1
3FA7:0115 B43F MOV AH,3F
3FA7:0117 CD21 INT 21 ; read it in
3FA7:0119 E8CE03 CALL 04EA
3FA7:011C 1F POP DS
3FA7:011D 07 POP ES
3FA7:011E 724E JB 016E ; bad format error
3FA7:0120 3D1E00 CMP AX,001E
3FA7:0123 7519 JNZ 013E ; .COM file (?)
3FA7:0125 833E740500 CMP WORD PTR [max_par],+00
3FA7:012A 7505 JNZ 0131 ; MAX Paragraphs needed above
3FA7:012C C6066705FF MOV BYTE PTR [hgh_low],FF ; set high / low switch
3FA7:0131 A16805 MOV AX,[pgm_hdr]
3FA7:0134 3D4D5A CMP AX,5A4D ; check if EXE format
3FA7:0137 7408 JZ 0141
3FA7:0139 3D5A4D CMP AX,4D5A
3FA7:013C 7403 JZ 0141 ; load EXE program
3FA7:013E E9C201 JMP 0303 ; its a .COM prog
3FA7:0141 A16C05 MOV AX,[pgm_siz] ; get size in pages
3FA7:0144 B105 MOV CL,05
3FA7:0146 D3E0 SHL AX,CL ; convert to paragraphs
3FA7:0148 2B067005 SUB AX,[hdr_siz] ; subtract header size
3FA7:014C A35705 MOV [ld_siz],AX ; save load module size
3FA7:014F F606520502 TEST BYTE PTR [exe_fnc],02
3FA7:0154 742B JZ 0181 ; go load program
3FA7:0156 C43E4E05 LES DI,[prm_off]
3FA7:015A 26 ES:
3FA7:015B 8B05 MOV AX,[DI] ; get segment to load
3FA7:015D A38405 MOV [str_seg],AX ; overlay and store it
3FA7:0160 26 ES:
3FA7:0161 8B4502 MOV AX,[DI+02]
3FA7:0164 A35505 MOV [relo_fctr],AX ; same for overlay offset
3FA7:0167 E9BA00 JMP 0224
3FA7:016A B008 MOV AL,08
3FA7:016C EB02 JMP 0170 ; not enough mem error
3FA7:016E B00B MOV AL,0B
3FA7:0170 50 PUSH AX
3FA7:0171 2E CS:
3FA7:0172 8B1E5305 MOV BX,[channel]
3FA7:0176 E86803 CALL 04E1
3FA7:0179 B43E MOV AH,3E
3FA7:017B CD21 INT 21 ; close the file (?)
3FA7:017D 58 POP AX
3FA7:017E E99703 JMP 0518 ; exit (?) error handler
3FA7:0181 50 PUSH AX
3FA7:0182 BBFFFF MOV BX,FFFF
3FA7:0185 1E PUSH DS
3FA7:0186 B448 MOV AH,48
3FA7:0188 CD21 INT 21 ; find available mem
3FA7:018A 1F POP DS
3FA7:018B 58 POP AX
3FA7:018C 051000 ADD AX,0010 ; add psp size to load module
3FA7:018F 83FB11 CMP BX,+11
3FA7:0192 72D6 JB 016A ; not enough mem for PSP + 1
3FA7:0194 3BC3 CMP AX,BX ; do we have enough mem
3FA7:0196 77D2 JA 016A ; not enough mem
3FA7:0198 803E670500 CMP BYTE PTR [hgh_low],00
3FA7:019D 7518 JNZ 01B7 ; no high\low problems
3FA7:019F 03067205 ADD AX,[min_par] ; add min mem needed
3FA7:01A3 72C5 JB 016A ; not enough mem
3FA7:01A5 3BC3 CMP AX,BX
3FA7:01A7 77C1 JA 016A ; don't have minimum needed
3FA7:01A9 2B067205 SUB AX,[min_par]
3FA7:01AD 03067405 ADD AX,[max_par]
3FA7:01B1 7204 JB 01B7 ; overflow - not enough mem
3FA7:01B3 3BC3 CMP AX,BX
3FA7:01B5 7602 JBE 01B9 ; allocate max needed
3FA7:01B7 8BC3 MOV AX,BX ; or all that we can < MAX
3FA7:01B9 1E PUSH DS
3FA7:01BA 8BD8 MOV BX,AX
3FA7:01BC 891E6305 MOV [new_siz],BX ; save amount requested
3FA7:01C0 B448 MOV AH,48
3FA7:01C2 CD21 INT 21 ; allocate it
3FA7:01C4 1F POP DS
3FA7:01C5 72A3 JB 016A ; not enough mem
3FA7:01C7 A36505 MOV [psp_seg],AX ; save new seg
3FA7:01CA 051000 ADD AX,0010 ; pt to org 100
3FA7:01CD 803E670500 CMP BYTE PTR [hgh_low],00
3FA7:01D2 740B JZ 01DF ; test it again
3FA7:01D4 03066305 ADD AX,[new_siz] ; figure where it goes
3FA7:01D8 2B065705 SUB AX,[ld_siz] ; if we load it high
3FA7:01DC 2D1000 SUB AX,0010
3FA7:01DF A35505 MOV [relo_fctr],AX ; save the pointer
3FA7:01E2 A38405 MOV [str_seg],AX ; twice (?)
3FA7:01E5 3B068705 CMP AX,[ovrwrt]
3FA7:01E9 772A JA 0215 ; we're writing over ourself
3FA7:01EB 03065705 ADD AX,[ld_siz]
3FA7:01EF 3B068705 CMP AX,[ovrwrt]
3FA7:01F3 762F JBE 0224 ; we aren't writing over us
3FA7:01F5 803E670500 CMP BYTE PTR [hgh_low],00
3FA7:01FA 7425 JZ 0221 ; avoid loading it lower
3FA7:01FC 8BD0 MOV DX,AX ; compute the old starting
3FA7:01FE 2B166305 SUB DX,[new_siz] ; address, try and load it
3FA7:0202 03165705 ADD DX,[ld_siz] ; lower in mem
3FA7:0206 3B168705 CMP DX,[ovrwrt]
3FA7:020A 7715 JA 0221 ; can't load any lower
3FA7:020C A18705 MOV AX,[ovrwrt] ; load it as high as we
3FA7:020F 2B065705 SUB AX,[ld_siz] ; can without overwriting us
3FA7:0213 EBCA JMP 01DF ; test it again
3FA7:0215 8CCA MOV DX,CS
3FA7:0217 81C25900 ADD DX,0059 ; test if were over ourself
3FA7:021B 3BC2 CMP AX,DX ; again
3FA7:021D 73D6 JNB 01F5 ; lower it if highlow
3FA7:021F EBDB JMP 01FC ; else lower it automatically
3FA7:0221 E946FF JMP 016A ; not enough mem err
3FA7:0224 8B167005 MOV DX,[hdr_siz] ; get the header size
3FA7:0228 52 PUSH DX
3FA7:0229 B104 MOV CL,04
3FA7:022B D3E2 SHL DX,CL ; convert it to bytes
3FA7:022D 58 POP AX
3FA7:022E B10C MOV CL,0C
3FA7:0230 D3E8 SHR AX,CL
3FA7:0232 8BC8 MOV CX,AX ; and store in cx:dx
3FA7:0234 8B1E5305 MOV BX,[channel]
3FA7:0238 1E PUSH DS
3FA7:0239 B80042 MOV AX,4200
3FA7:023C CD21 INT 21 ; move mfp to load module
3FA7:023E 1F POP DS
3FA7:023F 8B1E5705 MOV BX,[ld_siz]
3FA7:0243 81FB0010 CMP BX,1000 ; is file bigger than 64k
3FA7:0247 7203 JB 024C
3FA7:0249 BBE00F MOV BX,0FE0
3FA7:024C 291E5705 SUB [ld_siz],BX ; read in at most FE00 bytes
3FA7:0250 53 PUSH BX ; save count
3FA7:0251 B104 MOV CL,04
3FA7:0253 D3E3 SHL BX,CL ; convert para-s to bytes
3FA7:0255 8BCB MOV CX,BX
3FA7:0257 8B1E5305 MOV BX,[channel]
3FA7:025B 1E PUSH DS
3FA7:025C 8E1E8405 MOV DS,[str_seg] ; point to start segment
3FA7:0260 33D2 XOR DX,DX
3FA7:0262 51 PUSH CX ; save the count
3FA7:0263 E87B02 CALL 04E1
3FA7:0266 B43F MOV AH,3F
3FA7:0268 CD21 INT 21 ; read in the load module
3FA7:026A E87D02 CALL 04EA
3FA7:026D 59 POP CX
3FA7:026E 1F POP DS
3FA7:026F 3BC8 CMP CX,AX ; did we hit eof
3FA7:0271 5B POP BX
3FA7:0272 750B JNZ 027F
3FA7:0274 011E8405 ADD [str_seg],BX ; compute next load address
3FA7:0278 833E570500 CMP WORD PTR [ld_siz],+00
3FA7:027D 75C0 JNZ 023F ; we haven't reached eof
3FA7:027F 8B0E5505 MOV CX,[relo_fctr] ; start offset (!) not an offset
3FA7:0283 A17605 MOV AX,[stk_seg] ; read in stk_seg
3FA7:0286 03C1 ADD AX,CX ; compute new stack segment
3FA7:0288 A35F05 MOV [new_stk],AX ; save it for later
3FA7:028B A17805 MOV AX,[stk_sp] ; get new SP value
3FA7:028E A35D05 MOV [nstk_sp],AX ; save it for later
3FA7:0291 C4067C05 LES AX,[str_ip] ; initial start offset
3FA7:0295 A35905 MOV [strt_off],AX ; save it
3FA7:0298 8CC0 MOV AX,ES ; psp segment
3FA7:029A 03C1 ADD AX,CX ; + relocation factor
3FA7:029C A35B05 MOV [strt_seg],AX ; = start segment, save it!
3FA7:029F 33C9 XOR CX,CX
3FA7:02A1 8B168005 MOV DX,[0580] ; get ptr to relocation tble
3FA7:02A5 8B1E5305 MOV BX,[channel]
3FA7:02A9 1E PUSH DS
3FA7:02AA B80042 MOV AX,4200 ; move file ptr to table
3FA7:02AD CD21 INT 21
3FA7:02AF 1F POP DS
3FA7:02B0 7303 JNB 02B5
3FA7:02B2 E9B9FE JMP 016E ; bad format error
3FA7:02B5 8B166E05 MOV DX,[relo_itm] ; # of relocation items
3FA7:02B9 52 PUSH DX ; the pgm_hdr is done, use the
3FA7:02BA BA6805 MOV DX,pgm_hdr ; area for 7 relocation items
3FA7:02BD B91C00 MOV CX,001C ; 7 * 4 = 1C
3FA7:02C0 2E CS:
3FA7:02C1 8B1E5305 MOV BX,[channel]
3FA7:02C5 1E PUSH DS
3FA7:02C6 E81802 CALL 04E1
3FA7:02C9 B43F MOV AH,3F
3FA7:02CB CD21 INT 21 ; read it in
3FA7:02CD E81A02 CALL 04EA
3FA7:02D0 07 POP ES
3FA7:02D1 5A POP DX ; # of items to adjust
3FA7:02D2 72DE JB 02B2 ; bad format error
3FA7:02D4 B90700 MOV CX,0007 ; 7 items in buffer
3FA7:02D7 BF6805 MOV DI,pgm_hdr ; pt to the first
3FA7:02DA 2E CS:
3FA7:02DB 8B365505 MOV SI,[relo_fctr]
3FA7:02DF 83FA00 CMP DX,+00 ; are we done ?
3FA7:02E2 7503 JNZ 02E7 ; nope
3FA7:02E4 E9CD00 JMP 03B4 ; yep
3FA7:02E7 26 ES:
3FA7:02E8 C51D LDS BX,[DI] ; get pointer to one
3FA7:02EA 8CD8 MOV AX,DS ; add the relocation
3FA7:02EC 03C6 ADD AX,SI ; factor for item to be
3FA7:02EE 8ED8 MOV DS,AX ; updated in memory
3FA7:02F0 8B07 MOV AX,[BX] ; get it
3FA7:02F2 03C6 ADD AX,SI ; adjust it
3FA7:02F4 8907 MOV [BX],AX ; put it back
3FA7:02F6 83C704 ADD DI,+04 ; pt to next item
3FA7:02F9 4A DEC DX ; one less to go
3FA7:02FA E2E3 LOOP 02DF ; used up 7 items yet ?
3FA7:02FC 06 PUSH ES
3FA7:02FD 1F POP DS
3FA7:02FE EBB9 JMP 02B9 ; read some more in
3FA7:0300 E967FE JMP 016A
3FA7:0303 2E CS:
3FA7:0304 F606520502 TEST BYTE PTR [exe_fnc],02
3FA7:0309 740C JZ 0317 ; loading a program
3FA7:030B 2E CS:
3FA7:030C C5364E05 LDS SI,[prm_off] ; pt to parm block
3FA7:0310 AD LODSW ; read in the address
3FA7:0311 2E CS: ; for overlay
3FA7:0312 A38405 MOV [str_seg],AX ; store it
3FA7:0315 EB41 JMP 0358 ; go read it in
3FA7:0317 BBFFFF MOV BX,FFFF
3FA7:031A B448 MOV AH,48
3FA7:031C CD21 INT 21 ; how much mem available
3FA7:031E 0BDB OR BX,BX ; none ?
3FA7:0320 74DE JZ 0300 ; not enough mem error
3FA7:0322 2E CS:
3FA7:0323 891E6305 MOV [new_siz],BX ; store how much we got
3FA7:0327 B448 MOV AH,48
3FA7:0329 CD21 INT 21 ; and al